home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-02 / mkerr101.zip / MKERR.DOC < prev    next >
Text File  |  1991-08-04  |  12KB  |  349 lines

  1.  
  2. ManuSoft MkErr Error device for Turbo Pascal 6.0      THIS IS Public Domain
  3.  
  4.                        Version 1.01
  5.  
  6.  I dropped out the example program ErrTest in my last posting
  7.  MkErr100. I am  sorry for this.
  8.  
  9.  Here is a little error device I wrote for Turbo Pascal.
  10.  The history of device is that my boss wrote some fancy programs
  11.  with TVision, but he is not a "real" programmer so the
  12.  programs run nice until something unwanted happens like file 
  13.  that should be there isn't.
  14.  
  15.  Look end of file for changes to MkErr 1.00 package.
  16.  
  17.  
  18. What does it do ?
  19.  
  20.  MkErr let you build an error handler to pascal programs. Your handler
  21.  is called automatically on error. You can choose in errorhandler
  22.  what to do then, halt/print message/continue etc..
  23.  
  24.  Not only that MkErr let you make LOCAL errorhandles too.
  25.  
  26.  First, you setup errorhandler with MkBuf.ErrSet procedure
  27.  
  28.  ErrSet saves its own return address to internal MkErr.rbuf stack
  29.  and returns always false value. when error occurs, Turbo Pascal
  30.  ExitProc routine (rerouted to MkErr.Errh by errset function) starts
  31.  and restores the saved information from rbuf stack. Errh then return
  32.  with the True value. This makes Turbo Pascal to continue code from
  33.  inside the errset IF clause in your program instead of printing
  34.  runtime err and halt.
  35.  
  36.  You can get some picture of program from example program I
  37.  wrote named errtest.pas.
  38.  
  39.  
  40. What do you do ?
  41.  
  42.   0. You have to put error device in your program uses line
  43.      
  44.      "uses MkErr;"
  45.  
  46.   1. INIT: Error device saves programs exitproc pointer.
  47.      if you load other TPUs' that reroutes this pointer
  48.      I suggest you to run MkErr.Init as first thing in
  49.      your program. this way you can save yourself from
  50.      mixing up exitcodes (like if you have an communication
  51.      TPU which closes all communication on exit. Communication
  52.      TPU now thinks it is time to say goodbye, if installed
  53.      before MkErr.)
  54.  
  55.   
  56.   2. Now is your turn to wake up the error device:
  57.      You should put next kind of if clause in your program
  58.      somewhere (BEFORE any error of course):
  59.      
  60.      if errset then begin
  61.        {YOUR ERROR HANDLER IS HERE}
  62.      end;
  63.      
  64.      errset routine saves the point program is. this is the 'then' 
  65.      clause in the above code. Now errh routine takes advantage
  66.      of this saved information and when the fuse blows (ie. a
  67.      run-time error occurs) errh is activated instead of SYSTEM
  68.      tpus' exitcode program. errh does not stop the program, but
  69.      instead it starts running the code inside the errset if
  70.      clause.
  71.      
  72.   3.  WARNING:
  73.       To avoid problems you should release errset at end of
  74.       every object that activates error device
  75.       (that is, programs that uses errset routine !)
  76.  
  77.      procedure myloader;
  78.      begin
  79.        if errset then
  80.          {YOUR ERROR HANDLER IS HERE}
  81.        end;
  82.        {YOUR CODE HEAR}
  83.        errfree;
  84.      end;
  85.       
  86.      If you don't release MkErr and error occurs before next installa-
  87.      tion of errset in the caller of "myloader" then errh switch prog-
  88.      ram to run from "myloader" if clause WITHOUT HAVING the "myloader"
  89.      return address in stack ! this crashes your code for sure.
  90.      
  91.      The opposite situation works fine. If you load your errset in 
  92.      main program and error occurs in your, say, re-entrant code,
  93.      errset just waste all the information pushed to program stack
  94.      and continues from errset if clause.
  95.      
  96.   4. You should call done procedure at the end of your program just to
  97.      make sure everything is clear for exit.
  98.  
  99.      begin
  100.       init;
  101.       .
  102.       .
  103.       done;
  104.      end;
  105.      
  106.  
  107.   5. so, what you need is:
  108.  
  109.  
  110.      Program My_Program;
  111.      uses ..........,mkerr;
  112.  
  113.      procedure To_Be_Error_Checked(...);
  114.      begin
  115.       if errset then begin
  116.         My_Error:=IoResult;  {Clear all the occurred errors}
  117.         .
  118.         .
  119.         .
  120.         {$if you put here an exit clause, be care that you use the ERRFREE}
  121.         errfree;
  122.         exit;
  123.         {$endif}
  124.       end;
  125.       .
  126.       .
  127.       .
  128.       .
  129.       errfree;
  130.       exit;
  131.      end;
  132.  
  133.      begin
  134.       .
  135.       .
  136.       done;
  137.      end;
  138.  
  139.  NOTE:
  140.   MkErr does not clear any heap variables/objects nor does it close
  141.   any files. All this you should write in your errorhandler.
  142.  
  143.   You should be very careful with the code INSIDE the errorhandler. You
  144.   can guess what happens, if you make an error there..
  145.  
  146.  While error device is quite dangerous when misused I think it can solve
  147.  some annoying problems writing turbo pascal code. while your code can
  148.  be straightforward and your error handler smart your code would be
  149.  a bit faster while more compact.
  150.  
  151.  I served 16 occurrence for nested errset to happen. If you think you need
  152.  more, be my guest and change the constant value at the start of MkErr
  153.  tpu named "NestErr = 16" to what ever you desire. MkErr reserves data
  154.  from your programs data segment (Nesterr) * 7 bytes + 8 bytes vars.
  155.   
  156.  What should one write on his/her error handler then ?
  157.  
  158.  - You of course should manipulate the environment so that you can continue
  159.    error free.
  160.  
  161.  - You can exit from the routine. The lower in the mkerr stream you
  162.    place the 'if errset' clause, the lower the system automatically
  163.    exits.
  164.  
  165.    e.g.
  166.    
  167.    -Main
  168.       -My_Prog_1st_generation
  169.          -if errset
  170.          -My_Prog_2nd_generation
  171.             -My_Prog_3rd_generation
  172.                -SYSTEM.RESET
  173.                   -Error(goes in to errset, so situation comes like this:)
  174.                  
  175.    -Main
  176.       -My_Prog_1st_generation
  177.          -if errset
  178.             -ERROR_CODE
  179.             
  180.  You can place errset to even in your main program.
  181.  
  182.  Please examine errtest.pas while it is too hard to me explain all the 
  183.  things you can do with errtest the program shows a quite a bit of them.
  184.  
  185.  
  186. WHATS NEW ?
  187.  
  188. MkErr 1.01 versus 1.00
  189.  
  190.  Mainly I reposted this package because I failed badly while repacking
  191.  it to zip.  I dropped out the example program ErrTest in my last posting
  192.  MkErr100. I am  sorry for this.
  193.  
  194.  MkErr 1.01 Errorhandler is now wiser. In some cases it hanged the 
  195.  machine. For example if you did not put ErrFree / Done methods 
  196.  to their place. This is now fixed.
  197.  
  198.  Some new stuff is added:
  199.  continue   Procedure to continue the program from error.
  200.  halt       Rerouted system.halt procedure for safe halting the program.
  201.  
  202.  
  203.  
  204. MkErr 1.01 Functions and descriptions
  205.  
  206.  
  207. Init procedure
  208.  
  209.  Init procedure resets MkErr device to its initial inactive state.
  210.  
  211. Done procedure
  212.  
  213.  Done procedure resets MkErr device to its final inactive state.
  214.   
  215. errset function
  216.  
  217.  Returns always false state while errh returns always true.
  218.  
  219.  Errset is program place recorder. It saves the point where program is
  220.  running to rbuf buffer. Data is used by errh error handler to go back
  221.  to "if" clause written using this function. 
  222.  
  223.  
  224.  
  225. Errh function
  226.  
  227.  Returns always true state while errset returns always false.
  228.  
  229.  This is inside use function for the errorhandler. It returns program
  230.  to line that previously included errset funcion. 
  231.  
  232.  Why is it in the interface part? 
  233.  
  234.  Well you can call errh within your program to state your own errors
  235.  or whatever. 
  236.  
  237.  1. Remember that errh call halt procedure if there is no error when 
  238.     it starts. You can state errh not to call stop even when called without 
  239.     erroraddr set by setting MkErr boolean variable nehalt to FALSE. 
  240.     (nehalt=non error halt).
  241.     
  242.     Another way around is by putting non-nil value to system.tpu erroraddr 
  243.     pointer variable. This is dangerous though. If continue command is 
  244.     used in error handler, program freezes. (Until the value you gave
  245.     to erroraddr is address of some line in your program.)
  246.     
  247.  2. Errh calls halt also when there is no recorded information in rbuf
  248.     stack. This is obvious, where else could it go without having address ?    
  249.     This way if errorhandler is not activated with errset all the runtime
  250.     errors are handled the normal way (runtime error...)
  251.  
  252.  errh does NOT clear the rbuf recorded with errset. If another error 
  253.  happens before errfree, errh is launched again.
  254.  
  255.  MkErr 1.01 Errorhandler is now wiser. In some cases it hanged the 
  256.  machine. For example if you did not put ErrFree / Done methods 
  257.  to their place. This is now fixed.
  258.  
  259.  Why is it in the interface part? 
  260.  
  261.  Well you can call errh within your program to state your own errors
  262.  or whatever. 
  263.  
  264.  1. Remember that errh call halt procedure if there is no error when 
  265.     it starts. You can state errh not to call stop even when called without 
  266.     erroraddr set by setting MkErr boolean variable nehalt to FALSE. 
  267.     (nehalt=non error halt).
  268.     
  269.     Another way around is by putting non-nil value to system.tpu erroraddr 
  270.     pointer variable. This is dangerous though. If continue command is 
  271.     used in error handler, program freezes. (Until the value you gave
  272.     to erroraddr is address of some line in your program.)
  273.     
  274.  2. Errh calls halt also when there is no recorded information in rbuf
  275.     stack. This is obvious, where else could it go without having address ?    
  276.     This way if errorhandler is not activated with errset all the runtime
  277.     errors are handled the normal way (runtime error...)
  278.  
  279.  
  280. errfree procedure
  281.  
  282.   Errfree is program to pop out last recorded information from the rbuf
  283.   stack. That is all it does.
  284.  
  285.  
  286. Halt Procedure         Override of SYSTEM TPU Halt to secure program halting.
  287.  
  288.  I noticed that sometimes when you gave halt command the program plugged
  289.  the errh routine and started errorhandler without good reason. I think
  290.  when you give turbo pascal the command halt you mean it. Now halt command
  291.  has been rerouted by MkErr. When you give halt, MkErr first clears up
  292.  itself and then turns to SYSTEM TPUs halt command.
  293.  
  294.  If you for some reason need to use real halt command, you can do that by
  295.  pointing to turbo pascal to use System.tpu's halt:
  296.  
  297.  halt;         {this goes to mkerr.tpu halt}
  298.  system.halt;  {this goes straight to system.tpu halt}
  299.  mkerr.halt;   {this always goes to mkerr.tpu halt}
  300.  
  301.  
  302. continue procedure     Continues program after error line.
  303.  
  304.  While trying to build code with MkErr I came up with the idea that you
  305.  should be able to continue program from the point it failed. This can
  306.  be done in turbo pascal with erroraddr variable where the address of
  307.  the line error occured is. example:
  308.  
  309.   if errtest then begin
  310.    writeln('File Not Found, give file name');
  311.    continue;
  312.   end;
  313.   assign(f,paramstr(0));
  314.   reset(f);
  315.   .
  316.   .
  317.   .
  318.   
  319.  If error occurs in reset(f) command (e.g. file not found), program continues
  320.  running inside if clause. (writing file not found on the screen).
  321.  
  322.  Continue statement then continues program from the next program line AFTER
  323.  reset command. 
  324.  
  325.  I have not found a way to go back to reset(f) itself in the program, since
  326.  failures can be caused by e.g. div by zero statement. Size of these routines
  327.  are different and information posted to errorhandler is not enough to 
  328.  turn back to reset(f) line.
  329.   
  330.  
  331. Author 
  332.       
  333.  Enjoy your self.
  334.  
  335.  I have tested MkErr for some time now, but I do NOT quarantee anything nor
  336.  will I take any response of whatever the program does. 
  337.  
  338.  Please Please.
  339.   If you make any major changes or
  340.   Notice bugs in program please let me know about them.
  341.   Any ideas are welcome too.
  342.   
  343.  Keep in touch
  344.    ManuSoft
  345.    Manu Kemppainen            Mail : manu@stekt.oulu.fi
  346.    Yliopistokatu 32 B 212
  347.    90570 Oulu                 Phone: +358-81-363374
  348.  
  349.